package com.nttdata.ta.user.service.impl;

import com.nttdata.ta.common.dto.LoginRequest;
import com.nttdata.ta.common.dto.LoginResponse;
import com.nttdata.ta.common.dto.RegisterRequest;
import com.nttdata.ta.common.dto.UserDTO;
import com.nttdata.ta.common.entity.User;
import com.nttdata.ta.common.util.JwtUtil;
import com.nttdata.ta.user.repository.UserRepository;
import com.nttdata.ta.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    
    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        log.info("尝试登录用户: {}", loginRequest.getUsername());
        User user = userRepository.findByUsername(loginRequest.getUsername())
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        
        if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
            throw new BadCredentialsException("密码错误");
        }
        
        if (!user.isEnabled()) {
            log.warn("用户 {} 已被禁用，拒绝登录", user.getUsername());
            throw new BadCredentialsException("账号已被禁用，请联系管理员");
        }
        
        String token = jwtUtil.generateToken(user.getUsername(), user.getId());
        UserDTO userDTO = convertToDTO(user);
        
        log.info("用户登录成功: {}", user.getUsername());
        return new LoginResponse(token, userDTO);
    }
    
    @Override
    @Transactional
    public User register(RegisterRequest registerRequest) {
        log.info("注册新用户: {}", registerRequest.getUsername());
        
        if (userRepository.existsByUsername(registerRequest.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        if (registerRequest.getEmail() != null && userRepository.existsByEmail(registerRequest.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setEmail(registerRequest.getEmail());
        user.setFullName(registerRequest.getFullName());
        user.setEnabled(true);
        user.setRole("ROLE_USER");
        
        User savedUser = userRepository.save(user);
        log.info("用户注册成功: {}", savedUser.getUsername());
        
        return savedUser;
    }
    
    @Override
    @Transactional
    public User registerAdmin(RegisterRequest registerRequest) {
        log.info("注册新管理员: {}", registerRequest.getUsername());
        
        if (userRepository.existsByUsername(registerRequest.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        if (registerRequest.getEmail() != null && userRepository.existsByEmail(registerRequest.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setEmail(registerRequest.getEmail());
        user.setFullName(registerRequest.getFullName());
        user.setEnabled(true);
        user.setRole("ROLE_ADMIN");
        
        User savedUser = userRepository.save(user);
        log.info("管理员注册成功: {}", savedUser.getUsername());
        
        return savedUser;
    }
    
    @Override
    public UserDTO getUserById(Long id) {
        log.info("获取用户ID: {}", id);
        return userRepository.findById(id)
                .map(this::convertToDTO)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }
    
    @Override
    public List<UserDTO> getAllUsers() {
        log.info("获取所有用户");
        return userRepository.findAll().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional
    public UserDTO updateUser(Long id, UserDTO userDTO) {
        log.info("更新用户ID: {}", id);
        
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        if (userDTO.getEmail() != null) {
            user.setEmail(userDTO.getEmail());
        }
        
        if (userDTO.getFullName() != null) {
            user.setFullName(userDTO.getFullName());
        }
        
        if (userDTO.isEnabled() != user.isEnabled()) {
            user.setEnabled(userDTO.isEnabled());
        }
        
        User updatedUser = userRepository.save(user);
        log.info("用户更新成功: {}", updatedUser.getUsername());
        
        return convertToDTO(updatedUser);
    }
    
    @Override
    @Transactional
    public void deleteUser(Long id) {
        log.info("删除用户ID: {}", id);
        
        if (!userRepository.existsById(id)) {
            throw new RuntimeException("用户不存在");
        }
        
        userRepository.deleteById(id);
        log.info("用户删除成功, ID: {}", id);
    }
    
    @Override
    public boolean validateToken(String token) {
        try {
            String username = jwtUtil.getUsernameFromToken(token);
            User user = userRepository.findByUsername(username)
                    .orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
            
            if (!user.isEnabled()) {
                log.warn("用户 {} 已被禁用，令牌验证失败", username);
                return false;
            }
            
            return jwtUtil.validateToken(token, username);
        } catch (Exception e) {
            log.error("验证令牌失败", e);
            return false;
        }
    }
    
    @Override
    public Long getUserIdFromToken(String token) {
        return jwtUtil.getUserIdFromToken(token);
    }
    
    private UserDTO convertToDTO(User user) {
        return new UserDTO(
                user.getId(),
                user.getUsername(),
                user.getEmail(),
                user.getFullName(),
                user.isEnabled(),
                user.getRole()
        );
    }
} 